import java.io.File;
import gui.SWTCodegGUI;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import codeg.Codeg;


public class TextCodegGUI implements SWTCodegGUI {
    private TextCodeg codeg;
    private Label textLabel = null;
    
    public void populate(final Composite content)
    {
        content.setLayout(new GridLayout(1, false));
        
        textLabel = new Label(content, SWT.WRAP);
        
        if (codeg.getOption() == OPTION.TEXT && codeg.getText() == null)
            textLabel.setText("No text yet. Click on Edit to change.");
        else
            textLabel.setText(trimText(getText()));
        textLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        
        final Button buttonEdit = new Button(content, SWT.PUSH);
        buttonEdit.setText("Edit");
        buttonEdit.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
        MouseListener editML = new MouseListener()
        {
            public void mouseUp(MouseEvent e)
            {
                    edit(content.getDisplay());
            }
            public void mouseDown(MouseEvent e) {};
            public void mouseDoubleClick(MouseEvent e) {};
        };
        buttonEdit.addMouseListener(editML);
    }
    
    private String trimText(String text) {
        int lineCount = 0;
        int last= 0, index = text.indexOf('\n', 0);
        String result = "";
        while (index != -1 && lineCount < 5) {
            lineCount++;
            if (index - last < 60)
                result += text.substring(last, index);
            else    
                result += text.substring(last, last + 60) + "...";
            last = index;
            index = text.indexOf('\n', index + 1);
        }
        if (index != -1) result += "\n...";
        return result;
    }
    
    private String getText() {
        return codeg.getOption() == OPTION.TEXT ? 
            codeg.getText() : 
            TextCodeg.readTextFromFile(codeg.getFile());
    }
    
    private void edit(Display display) {
        TextDialog td = new TextDialog(codeg.getOption(), codeg.getFile(), codeg.getText(), codeg.getOutput());
        td.run(display);
        codeg.setOption(td.getOption());
        codeg.setFile(td.getFile());
        codeg.setText(td.getText());
        codeg.setOutput(td.getOutput());
        // FIXME: Fine for now, but should be changed if another option is added
        textLabel.setText(trimText(getText()));
        codeg.changed();
    }

    public Codeg getCodeg() {
        return codeg;
    }

    public void setCodeg(Codeg codeg) {
        this.codeg = (TextCodeg) codeg;
    }
}


class TextDialog {
    private OPTION option;
    private File file;
    private String text;
    private OUTPUT output;
    
    private Label labelFile;
    
    public TextDialog(OPTION option, File path, String text, OUTPUT output) {
        this.option = option;
        this.file = path;
        this.text = text;
        this.output = output;
    }
    
    public void run(Display display) {
        GridData gd;
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        
        final Group content = new Group(shell, SWT.SHADOW_NONE);
        content.setLayout(new GridLayout(3, false));
        
        final Button radioText = new Button(content, SWT.RADIO);
        radioText.setText("Use typed text");
        radioText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));
        
        final Text textContent = new Text(content, SWT.MULTI | SWT.BORDER);
        if (text != null)
            textContent.setText(text);
        gd = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
        gd.horizontalIndent = 12;
        textContent.setLayoutData(gd);
        
        
        final Button radioFile = new Button(content, SWT.RADIO);
        radioFile.setText("Use a file");
        radioFile.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));
        
        labelFile = new Label(content, SWT.LEFT);
        if (file != null)
            labelFile.setText("File: " + file.getAbsolutePath());
        else
            labelFile.setText("File: No file selected");
        gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
        gd.horizontalIndent = 12;        
        labelFile.setLayoutData(gd);
        
        final Button buttonSelect = new Button(content, SWT.PUSH);
        buttonSelect.setText("Select file");
        buttonSelect.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
        MouseListener selectML = new MouseListener()
        {
            public void mouseUp(MouseEvent e)
            {
                selectFile(content);
            }
            public void mouseDown(MouseEvent e) {};
            public void mouseDoubleClick(MouseEvent e) {};
        };
        buttonSelect.addMouseListener(selectML);
        
        
        SelectionListener radioListener = new SelectionListener()
        {
            public void widgetSelected(SelectionEvent e) {
                labelFile.setEnabled(e.widget == radioFile);
                buttonSelect.setEnabled(e.widget == radioFile);
                textContent.setEnabled(e.widget == radioText);
            }
            public void widgetDefaultSelected(SelectionEvent e) {};
        };
        radioFile.addSelectionListener(radioListener);
        radioText.addSelectionListener(radioListener);

        radioText.setSelection(option == OPTION.TEXT);
        radioFile.setSelection(option == OPTION.FILE);
        textContent.setEnabled(option == OPTION.TEXT);
        labelFile.setEnabled(option == OPTION.FILE);
        buttonSelect.setEnabled(option == OPTION.FILE);
        
        Label labelOutputs = new Label(content, SWT.NONE);
        labelOutputs.setText("Output format: ");
        labelOutputs.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
        
        Group outputs = new Group(content, SWT.SHADOW_NONE);
        outputs.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
        outputs.setLayout(new FillLayout());
        
        final Button radioString = new Button(outputs, SWT.RADIO);
        radioString.setText("String");

        Button radioChararray = new Button(outputs, SWT.RADIO);
        radioChararray.setText("Character Array");
        
        radioString.setSelection(output == OUTPUT.STRING);
        radioChararray.setSelection(output == OUTPUT.CHARARRAY);
        
        Button buttonClose = new Button(content, SWT.PUSH);
        buttonClose.setText("Close");
        buttonClose.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 3, 1));
        buttonClose.addMouseListener(new MouseListener() {
            public void mouseUp(MouseEvent e) {
                shell.close();
                shell.dispose();
            }
            
            public void mouseDoubleClick(MouseEvent e) {}
            public void mouseDown(MouseEvent e) {}
        });
        
        shell.pack();
        shell.setSize(450, 250);

        shell.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                setOption(radioText.getSelection()? OPTION.TEXT : OPTION.FILE);
                setText(textContent.getText());
                setOutput(radioString.getSelection()? OUTPUT.STRING : OUTPUT.CHARARRAY);
            }
        });
        
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
    }
    
    private void selectFile(Composite content)
    {
        FileDialog dialog = new FileDialog(content.getShell(), SWT.OPEN);
        dialog.setText("Select a file");
        String fname = dialog.open();
        if (fname != null)
        {
            this.file = new File(fname);
            labelFile.setText("File: " + file.getAbsolutePath());
        }
    }

    public OPTION getOption() {
        return option;
    }

    public void setOption(OPTION option) {
        this.option = option;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File path) {
        this.file = path;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public OUTPUT getOutput() {
        return output;
    }

    public void setOutput(OUTPUT output) {
        this.output = output;
    }
}
